package beautiful.butterfly.distributed_service_container.automatic_discovery_service;

import beautiful.butterfly.distributed_service_container.application.Application;
import beautiful.butterfly.distributed_service_container.http.mvc.core.ClassSearcher;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * 自动发现服务
 */
public class AutomaticDiscoveryService
{

    public static ExecutorService executorService = null;
    //
    public static List<Callable> callableList = new ArrayList<Callable>();
    public static List<Future<Map<String, Object>>> futureList = new ArrayList<Future<Map<String, Object>>>();
    //
    public static ConcurrentHashMap<Callable, Future> callableToFutureMap = new ConcurrentHashMap<Callable, Future>();
    public static ConcurrentHashMap<Future, Callable> futureToCallableMap = new ConcurrentHashMap<Future, Callable>();

    public void service() throws IllegalAccessException, InstantiationException
    {
        /**
         * 进行服务发现,该服务只需要每次启动的时候进行发现,不用像动态服务一样动态进行加载
         */
        List<Class> classList = ClassSearcher.findAnnotationClassInClasspath(NeedToRegister.class, Application.getBasePackageName());
        //所有的服务自动生成实例 然后调用
        List<Service> serviceList = new ArrayList<Service>();
        for (Class clazz : classList)
        {
            System.out.println("当前需要注册的服务是:" + clazz.getName());
            Object object = clazz.newInstance();
            if (!(object instanceof Service))
            {
                throw new RuntimeException("请实现:" + Service.class.getName() + "接口");
            }
            Service service = (Service) object;
            serviceList.add(service);
        }
        AutomaticDiscoveryService.executorService = Executors.newFixedThreadPool(serviceList.size() + 1);

        for (final Service service :
                serviceList)
        {
            Callable callable = new Callable()
            {
                @Override
                public Object call() throws Exception
                {
                    try
                    {
                        service.service();
                    } catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                    return null;
                }
            };
            System.out.println("开始装载服务:" + service.getClass().getName());
            final Future<Map<String, Object>> future = AutomaticDiscoveryService.executorService.submit(callable);
            callableList.add(callable);
            futureList.add(future);
            callableToFutureMap.put(callable, future);
            futureToCallableMap.put(future, callable);
            System.out.println("装载服务成功:" + service.getClass().getName());
            //
            Runtime.getRuntime().addShutdownHook(new Thread()
            {
                @Override
                public void run()
                {
                    if (future != null)
                    {
                        future.cancel(true);
                    }
                }
            });//自动清理
        }


    }
}
